package com.iwhalecloud.bss.kite.cucc.service.reception;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.ztesoft.common.logger.api.ZLogger;
import com.ztesoft.common.logger.factory.ZLoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.reception.ICuccLoginService;
import com.iwhalecloud.bss.kite.cucc.client.dto.attr.UnicomRegion;
import com.iwhalecloud.bss.kite.cucc.client.dto.login.CuccLoginInfoDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.login.auth.CuccAuthLoginInfoDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalInfConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.UnicomRegionCache;
import com.ztesoft.bss.common.bo.LoginInfo;
import com.ztesoft.bss.common.bo.OrgInfo;
import com.ztesoft.bss.common.bo.PostInfo;
import com.ztesoft.bss.common.bo.PrivInfo;
import com.ztesoft.bss.common.bo.RoleInfo;
import com.ztesoft.bss.common.bo.SimpleLoginInfo;
import com.ztesoft.bss.common.bo.StaffInfo;
import com.ztesoft.bss.common.bo.UserInfo;
import com.ztesoft.bss.common.util.ContextUtil;

@Service
public class CuccLoginService implements ICuccLoginService {

    private static final ZLogger LOGGER = ZLoggerFactory.getLogger(CuccLoginService.class, KeyConsts.LOG_MODULE);

    @SuppressWarnings("deprecation")
    public void saveLoginInfo(String sessionId, CuccLoginInfoDTO cuccLoginInfo) {
        LoginInfo loginInfo = this.packLoginInfo(cuccLoginInfo);
        this.saveLoginInfo(sessionId, loginInfo);
    }

    private LoginInfo packLoginInfo(CuccLoginInfoDTO cuccLoginInfo) {
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setSuperAdminFlag(cuccLoginInfo.getSuperAdminFlag());
        loginInfo.setLoginIp(cuccLoginInfo.getLoginIp());

        this.packPostInfo(loginInfo, cuccLoginInfo);
        this.packRoleInfo(loginInfo, cuccLoginInfo);
        this.packUserInfo(loginInfo, cuccLoginInfo);
        this.packPrivInfo(loginInfo, cuccLoginInfo);
        this.packOrgInfo(loginInfo, cuccLoginInfo);

        return loginInfo;
    }

    private void packPostInfo(LoginInfo loginInfo, CuccLoginInfoDTO cuccLoginInfo) {
        List<PostInfo> postList = new ArrayList<>();
        loginInfo.setPostInfos(postList);
    }

    private void packRoleInfo(LoginInfo loginInfo, CuccLoginInfoDTO cuccLoginInfo) {
        if (!KiteListUtils.isEmpty(cuccLoginInfo.getRoleList())) {
            List<RoleInfo> userRoles = new ArrayList<>();
            cuccLoginInfo.getRoleList().forEach((role) -> {
                RoleInfo roleInfo = new RoleInfo();
                roleInfo.setSysRoleId(role.getId());
                roleInfo.setSysRoleName(role.getName());
                roleInfo.setSysRoleCode(role.getCode());
                roleInfo.setSysRoleType(role.getType());
                // roleInfo.setRegionId(Long.valueOf(role.getBelong()));

                userRoles.add(roleInfo);
            });

            loginInfo.setUserRoles(userRoles);
        }
    }

    private void packUserInfo(LoginInfo loginInfo, CuccLoginInfoDTO cuccLoginInfo) {
        if (Objects.nonNull(cuccLoginInfo.getUserInfo())) {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(cuccLoginInfo.getUserInfo().getUserId());
            userInfo.setUserName(cuccLoginInfo.getUserInfo().getUserName());
            userInfo.setUserCode(cuccLoginInfo.getUserInfo().getUserCode());
            userInfo.setPostId(0L);
            loginInfo.setUserInfo(userInfo);

            StaffInfo staffInfo = new StaffInfo();
            staffInfo.setStaffId(cuccLoginInfo.getUserInfo().getUserId());
            staffInfo.setStaffCode(cuccLoginInfo.getUserInfo().getUserCode());
            staffInfo.setStaffName(cuccLoginInfo.getUserInfo().getUserName());
            loginInfo.setStaffInfo(staffInfo);
        }
    }

    private void packOrgInfo(LoginInfo loginInfo, CuccLoginInfoDTO cuccLoginInfo) {
        if (Objects.nonNull(cuccLoginInfo.getOrgInfo())) {
            Long regionId = 0L;
            UnicomRegion unicomRegion = UnicomRegionCache.getOneUnicomRegion(cuccLoginInfo.getOrgInfo().getAreaCode());
            if (Objects.nonNull(unicomRegion)) {
                regionId = unicomRegion.getRegionId();
            }
            OrgInfo orgInfo = new OrgInfo();
            orgInfo.setOrgId(cuccLoginInfo.getOrgInfo().getOrgId());
            orgInfo.setOrgName(cuccLoginInfo.getOrgInfo().getOrgName());
            orgInfo.setOrgLevel(Long.valueOf(cuccLoginInfo.getOrgInfo().getOrgLevel()));
            orgInfo.setOrgCode(cuccLoginInfo.getOrgInfo().getOrgCode());
            orgInfo.setParentOrgId(cuccLoginInfo.getOrgInfo().getParentOrgId());
            orgInfo.setRegionId(regionId);
            loginInfo.setOrgInfo(orgInfo);

            UserInfo userInfo = loginInfo.getUserInfo();
            userInfo.setPostLanId(cuccLoginInfo.getOrgInfo().getEparchyCode());
            userInfo.setPostProvinceNbr(cuccLoginInfo.getOrgInfo().getProvinceCode());
            userInfo.setPostRegionId(regionId);
            loginInfo.setUserInfo(userInfo);
        }
    }

    private void packPrivInfo(LoginInfo loginInfo, CuccLoginInfoDTO cuccLoginInfo) {
        if (!KiteListUtils.isEmpty(cuccLoginInfo.getPrivList())) {
            List<PrivInfo> privList = new ArrayList<>();
            cuccLoginInfo.getPrivList().forEach((priv) -> {
                PrivInfo privInfo = new PrivInfo();
                privInfo.setPrivId(priv.getPrivId());
                privInfo.setPrivCode(priv.getPrivCode());
                privInfo.setPrivName(priv.getPrivName());

                // 操作id，操作对应url没有对应属性，暂时不设置
                privList.add(privInfo);
            });
            loginInfo.setPrivInfos(privList);
        }
    }

    @Override
    public void saveLoginInfoFromPortal(String sessionId, CuccAuthLoginInfoDTO cuccLoginInfo) {
        // ContextUtil.setHttpSessoinId(sessionId);
        LoginInfo loginInfo = this.packLoginInfoFromPortal(cuccLoginInfo);
        this.saveLoginInfo(sessionId, loginInfo);
    }

    private void saveLoginInfo(String sessionId, LoginInfo loginInfo){
        ContextUtil.setLoginInfo2LoginInfoThreadLocal(loginInfo);
        ContextUtil.putSimpleLoginInfo2ThreadLocal(null);
        SimpleLoginInfo simpleLoginInfo = ContextUtil.getSimpleLoginInfo();
        ContextUtil.putSimpleLoginInfo2ThreadLocal(simpleLoginInfo);
        ContextUtil.putLanId2ThreadLocal(loginInfo.getUserInfo().getPostLanId());
        Map<String, Object> extParams = ContextUtil.getLoginInfo().getUserInfo().getExtParams();
        if (KiteMapUtils.isEmpty(extParams)) {
            extParams = new HashMap<String, Object>();
        }

        UserInfo userInfo = ContextUtil.getLoginInfo().getUserInfo();
        extParams.put("session_id", sessionId);
        extParams.put("kite_session_id", ContextUtil.getHttpSessoinId());
        extParams.put("appId", LocalInfConsts.APP_ID);
        userInfo.setExtParams(extParams);
        // KiteContextCache.put(key, sessionId, expireTime);

        ContextUtil.getLoginInfo().setUserInfo(userInfo);
        ContextUtil.setLoginInfo(loginInfo);
        // ContextUtil.setLoginInfo2LoginInfoThreadLocal 里面会把角色清空
        List<RoleInfo> roleInfo = loginInfo.getUserRoles();
        if (KiteListUtils.isNotEmpty(roleInfo)) {
            ContextUtil.getLoginInfo().setUserRoles(roleInfo);
        }
    }

    private LoginInfo packLoginInfoFromPortal(CuccAuthLoginInfoDTO cuccLoginInfo) {
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setSuperAdminFlag(cuccLoginInfo.getSuperAdminFlag());
        loginInfo.setLoginIp(cuccLoginInfo.getLoginIp());

        this.packPostInfoFromPortal(loginInfo, cuccLoginInfo);
        this.packRoleInfoFromPortal(loginInfo, cuccLoginInfo);
        this.packUserInfoFromPortal(loginInfo, cuccLoginInfo);
        this.packPrivInfoFromPortal(loginInfo, cuccLoginInfo);
        this.packOrgInfoFromPortal(loginInfo, cuccLoginInfo);

        return loginInfo;
    }

    private void packPostInfoFromPortal(LoginInfo loginInfo, CuccAuthLoginInfoDTO cuccLoginInfo) {
        List<PostInfo> postList = new ArrayList<>();
        PostInfo postInfo = new PostInfo();
        postInfo.setPostId(Long.valueOf(Optional.ofNullable(cuccLoginInfo.getUserInfo().getDeptId()).orElse("0")));
        postInfo.setPostName(cuccLoginInfo.getUserInfo().getDeptName());
        postList.add(postInfo);
        loginInfo.setPostInfos(postList);
    }

    private void packRoleInfoFromPortal(LoginInfo loginInfo, CuccAuthLoginInfoDTO cuccLoginInfo) {
        if (!KiteListUtils.isEmpty(cuccLoginInfo.getUserRoles())) {
            List<RoleInfo> userRoles = new ArrayList<>();
            cuccLoginInfo.getUserRoles().forEach((role) -> {
                RoleInfo roleInfo = new RoleInfo();
                roleInfo.setSysRoleId(role.getSysRoleId());
                roleInfo.setSysRoleName(role.getSysRoleName());
                roleInfo.setSysRoleCode(role.getSysRoleCode());
                roleInfo.setSysCode(role.getSysCode());
//                roleInfo.setSysRoleType(role.getType());
//                roleInfo.setRegionId(Long.valueOf(role.getBelong()));

                userRoles.add(roleInfo);
            });

            loginInfo.setUserRoles(userRoles);
        }
    }

    private void packUserInfoFromPortal(LoginInfo loginInfo, CuccAuthLoginInfoDTO cuccLoginInfo) {
        if (Objects.nonNull(cuccLoginInfo.getUserInfo())) {
            Assert.hasText(cuccLoginInfo.getUserInfo().getName(), "获取运营平台登录信息缺失，未关联集客工号，请绑定集客工号后办理业务");
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(cuccLoginInfo.getUserInfo().getOaUserId());
            userInfo.setUserName(cuccLoginInfo.getUserInfo().getName());
            userInfo.setUserCode(cuccLoginInfo.getUserInfo().getNumber());
            userInfo.setPostId(0L);
            Map<String, Object> extParams = new HashMap<>();
            extParams.put("account", cuccLoginInfo.getUserInfo().getAccount());
            extParams.put("accountId", cuccLoginInfo.getUserInfo().getAccountId());
            extParams.put("phone",cuccLoginInfo.getUserInfo().getPhone());
            extParams.put("deptId",cuccLoginInfo.getUserInfo().getDeptId());
            userInfo.setExtParams(extParams);

            loginInfo.setUserInfo(userInfo);

            StaffInfo staffInfo = new StaffInfo();
            staffInfo.setStaffId(cuccLoginInfo.getUserInfo().getOaUserId());
            staffInfo.setStaffCode(KiteStringUtils.valueOf(cuccLoginInfo.getUserInfo().getLogin()));
            staffInfo.setStaffName(cuccLoginInfo.getUserInfo().getName());
            loginInfo.setStaffInfo(staffInfo);
        }
    }

    private void packOrgInfoFromPortal(LoginInfo loginInfo, CuccAuthLoginInfoDTO cuccLoginInfo) {
        if (Objects.nonNull(cuccLoginInfo.getOrgInfo())) {
            Long regionId = 0L;

            Assert.hasText(cuccLoginInfo.getOrgInfo().getCityCode(), "获取运营平台登录信息缺失，集客工号组机构为空，请补全工号组织机构信息");
            UnicomRegion unicomRegion = UnicomRegionCache.getOneUnicomRegion(cuccLoginInfo.getOrgInfo().getCityCode());
            if (Objects.nonNull(unicomRegion)) {
                regionId = unicomRegion.getRegionId();
            }
            OrgInfo orgInfo = new OrgInfo();
            orgInfo.setOrgId(Long.valueOf(Optional.ofNullable(cuccLoginInfo.getOrgInfo().getOrgId()).orElse("0")));
            orgInfo.setOrgName(cuccLoginInfo.getOrgInfo().getOrgName());
            orgInfo.setOrgLevel(Long.valueOf(cuccLoginInfo.getOrgInfo().getOrgLevel()));
//            orgInfo.setOrgCode(cuccLoginInfo.getOrgInfo().getOrgCode());
            orgInfo.setParentOrgId(cuccLoginInfo.getOrgInfo().getParentOrgId());
            orgInfo.setRegionId(regionId);
//            orgInfo.setRegionName(Optional.ofNullable(unicomRegion).map(UnicomRegion::getRegionName).orElse(null));
            loginInfo.setOrgInfo(orgInfo);
            // 已跟门户确认ProvinceCode>EparchyCode>CityCode
            UserInfo userInfo = loginInfo.getUserInfo();
            userInfo.setPostLanId(cuccLoginInfo.getOrgInfo().getEparchyCode());
            userInfo.setPostProvinceNbr(cuccLoginInfo.getOrgInfo().getProvinceCode());
            userInfo.setPostRegionId(regionId);
            loginInfo.setUserInfo(userInfo);
        }
    }

    private void packPrivInfoFromPortal(LoginInfo loginInfo, CuccAuthLoginInfoDTO cuccLoginInfo) {

        if (!KiteListUtils.isEmpty(cuccLoginInfo.getPrivInfos())) {
            List<PrivInfo> privList = new ArrayList<>();
            cuccLoginInfo.getPrivInfos().forEach((priv) -> {
                PrivInfo privInfo = new PrivInfo();
                privInfo.setPrivId(priv.getPrivId());
                privInfo.setPrivCode(priv.getPrivCode());
                privInfo.setPrivName(priv.getPrivName());

                //操作id，操作对应url没有对应属性，暂时不设置
                privList.add(privInfo);
            });
            loginInfo.setPrivInfos(privList);
        }
    }
}
